import crypto from 'crypto'
import { prisma } from '@/lib/database'
import { config } from '@/config/env'
import {
  ValidationError,
  ConflictError,
  NotFoundError
} from '@/middleware/errorHandler'

// 类型定义
export interface CreateApiKeyData {
  name: string
  permissions?: string[]
  rateLimitPerHour?: number
  expiresAt?: Date
}

export interface ApiKeyInfo {
  id: string
  name: string
  keyPrefix: string
  permissions: string[]
  rateLimitPerHour: number
  lastUsedAt?: Date
  lastUsedIp?: string
  expiresAt?: Date
  createdAt: Date
  updatedAt: Date
}

export interface ApiKeyWithSecret {
  apiKey: ApiKeyInfo
  secretKey: string
}

export class ApiKeyService {
  // 生成API密钥
  private generateApiKey(): { prefix: string; secret: string; hash: string } {
    // 生成前缀 (8位随机字符)
    const prefix = crypto.randomBytes(4).toString('hex')
    
    // 生成密钥 (32位随机字符)
    const secret = crypto.randomBytes(16).toString('hex')
    
    // 完整的API密钥
    const fullKey = `bh_${prefix}_${secret}`
    
    // 生成哈希用于存储
    const hash = crypto
      .createHmac('sha256', config.apiKey.secret)
      .update(fullKey)
      .digest('hex')
    
    return {
      prefix: `bh_${prefix}`,
      secret: fullKey,
      hash
    }
  }

  // 验证API密钥
  verifyApiKey(apiKey: string): string {
    const hash = crypto
      .createHmac('sha256', config.apiKey.secret)
      .update(apiKey)
      .digest('hex')
    
    return hash
  }

  // 创建API密钥
  async createApiKey(developerId: string, data: CreateApiKeyData): Promise<ApiKeyWithSecret> {
    // 验证输入数据
    if (!data.name || data.name.length < 3) {
      throw new ValidationError('API key name must be at least 3 characters long')
    }

    if (data.name.length > 100) {
      throw new ValidationError('API key name must be less than 100 characters')
    }

    // 检查开发者是否存在
    const developer = await prisma.developer.findUnique({
      where: { id: developerId }
    })

    if (!developer) {
      throw new NotFoundError('Developer not found')
    }

    // 检查同名API密钥是否已存在
    const existingKey = await prisma.apiKey.findFirst({
      where: {
        developerId,
        name: data.name
      }
    })

    if (existingKey) {
      throw new ConflictError('API key with this name already exists')
    }

    // 检查API密钥数量限制
    const keyCount = await prisma.apiKey.count({
      where: { developerId }
    })

    if (keyCount >= 10) { // 限制每个开发者最多10个API密钥
      throw new ValidationError('Maximum number of API keys reached (10)')
    }

    // 生成API密钥
    const { prefix, secret, hash } = this.generateApiKey()

    // 创建API密钥记录
    const apiKey = await prisma.apiKey.create({
      data: {
        developerId,
        name: data.name,
        keyPrefix: prefix,
        keyHash: hash,
        permissions: data.permissions || [],
        rateLimitPerHour: data.rateLimitPerHour || 1000,
        expiresAt: data.expiresAt
      }
    })

    return {
      apiKey: this.formatApiKeyInfo(apiKey),
      secretKey: secret
    }
  }

  // 获取开发者的API密钥列表
  async getApiKeys(developerId: string): Promise<ApiKeyInfo[]> {
    const apiKeys = await prisma.apiKey.findMany({
      where: { developerId },
      orderBy: { createdAt: 'desc' }
    })

    return apiKeys.map(key => this.formatApiKeyInfo(key))
  }

  // 获取API密钥详情
  async getApiKey(developerId: string, keyId: string): Promise<ApiKeyInfo> {
    const apiKey = await prisma.apiKey.findFirst({
      where: {
        id: keyId,
        developerId
      }
    })

    if (!apiKey) {
      throw new NotFoundError('API key not found')
    }

    return this.formatApiKeyInfo(apiKey)
  }

  // 更新API密钥
  async updateApiKey(
    developerId: string, 
    keyId: string, 
    data: Partial<CreateApiKeyData>
  ): Promise<ApiKeyInfo> {
    // 验证API密钥是否存在且属于该开发者
    const existingKey = await prisma.apiKey.findFirst({
      where: {
        id: keyId,
        developerId
      }
    })

    if (!existingKey) {
      throw new NotFoundError('API key not found')
    }

    // 验证更新数据
    const updateData: any = {}

    if (data.name !== undefined) {
      if (!data.name || data.name.length < 3) {
        throw new ValidationError('API key name must be at least 3 characters long')
      }
      if (data.name.length > 100) {
        throw new ValidationError('API key name must be less than 100 characters')
      }

      // 检查同名API密钥
      const duplicateKey = await prisma.apiKey.findFirst({
        where: {
          developerId,
          name: data.name,
          id: { not: keyId }
        }
      })

      if (duplicateKey) {
        throw new ConflictError('API key with this name already exists')
      }

      updateData.name = data.name
    }

    if (data.permissions !== undefined) {
      updateData.permissions = data.permissions
    }

    if (data.rateLimitPerHour !== undefined) {
      if (data.rateLimitPerHour < 1 || data.rateLimitPerHour > 10000) {
        throw new ValidationError('Rate limit must be between 1 and 10000 requests per hour')
      }
      updateData.rateLimitPerHour = data.rateLimitPerHour
    }

    if (data.expiresAt !== undefined) {
      updateData.expiresAt = data.expiresAt
    }

    // 更新API密钥
    const updatedKey = await prisma.apiKey.update({
      where: { id: keyId },
      data: updateData
    })

    return this.formatApiKeyInfo(updatedKey)
  }

  // 删除API密钥
  async deleteApiKey(developerId: string, keyId: string): Promise<void> {
    const apiKey = await prisma.apiKey.findFirst({
      where: {
        id: keyId,
        developerId
      }
    })

    if (!apiKey) {
      throw new NotFoundError('API key not found')
    }

    await prisma.apiKey.delete({
      where: { id: keyId }
    })
  }

  // 通过API密钥查找开发者
  async findDeveloperByApiKey(apiKey: string): Promise<{ developer: any; apiKeyRecord: any } | null> {
    const keyHash = this.verifyApiKey(apiKey)

    const apiKeyRecord = await prisma.apiKey.findFirst({
      where: { keyHash },
      include: {
        developer: true
      }
    })

    if (!apiKeyRecord) {
      return null
    }

    // 检查API密钥是否过期
    if (apiKeyRecord.expiresAt && apiKeyRecord.expiresAt < new Date()) {
      return null
    }

    // 检查开发者状态
    if (apiKeyRecord.developer.status !== 'active') {
      return null
    }

    return {
      developer: apiKeyRecord.developer,
      apiKeyRecord
    }
  }

  // 更新API密钥使用记录
  async updateApiKeyUsage(keyId: string, ipAddress?: string): Promise<void> {
    // 验证IP地址格式，如果无效则设为null
    let validIp: string | null = null
    if (ipAddress && ipAddress !== 'unknown') {
      // 简单的IP地址格式验证
      const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
      if (ipRegex.test(ipAddress)) {
        validIp = ipAddress
      }
    }

    await prisma.apiKey.update({
      where: { id: keyId },
      data: {
        lastUsedAt: new Date(),
        lastUsedIp: validIp
      }
    })
  }

  // 格式化API密钥信息
  private formatApiKeyInfo(apiKey: any): ApiKeyInfo {
    return {
      id: apiKey.id,
      name: apiKey.name,
      keyPrefix: apiKey.keyPrefix,
      permissions: apiKey.permissions,
      rateLimitPerHour: apiKey.rateLimitPerHour,
      lastUsedAt: apiKey.lastUsedAt,
      lastUsedIp: apiKey.lastUsedIp,
      expiresAt: apiKey.expiresAt,
      createdAt: apiKey.createdAt,
      updatedAt: apiKey.updatedAt
    }
  }
}
